﻿/* 
 * 
 * Copyright 2013 Bendsoft. All rights reserved.
 * http://www.bendsoft.com
 * 
 * This code is distributed under the New BSD License (BSD).
 * 
 * @package     Camelot SharePoint Integration Library
 * @codeplex    http://camelottoolkit.codeplex.com
 * @license     New BSD License (BSD)
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Globalization;
using Camelot.SharePointIntegration.Client;

namespace Camelot.SharePointIntegration
{
    public static class Csv
    {
        private static string Escape(string value)
        {
            if (!string.IsNullOrEmpty(value))
                return value.Replace("\"", "\"\"");
            else
                return value;
        }

        public static string CreateCsv(ListData data, char delimiter) 
        {
            if (data == null || data.Rows == null)
                throw new ArgumentException("This method requires valid list data", "data");

            var builder = new StringBuilder();

            foreach (DataColumn column in data.Rows.Columns)
            {
                builder.Append((char)34 + column.ColumnName + (char)34);
                if (column.Ordinal < data.Rows.Columns.Count - 1)
                    builder.Append(delimiter);
            }
            builder.AppendLine();

            foreach (DataRow row in data.Rows.Rows)
            {
                foreach (DataColumn column in data.Rows.Columns)
                {
                    builder.Append((char)34);

                    if (row[column] == null || Convert.IsDBNull(row[column]))
                    {
                        builder.Append("NULL");

                    }
                    else if (row[column] is string)
                    {
                        builder.Append(Escape((string)row[column]));

                    }
                    else if (row[column] is DateTime)
                    {
                        builder.Append(((DateTime)row[column]).ToString("yyyy-MM-dd HH:mm:ss"));

                    }
                    else if (row[column] is bool)
                    {
                        builder.Append(((bool)row[column]) ? "True" : "False");

                    }
                    else if (row[column] is Guid)
                    {
                        builder.Append(((Guid)row[column]).ToString());

                    }
                    else if (row[column] is Int32)
                    {
                        builder.Append((Int32)row[column]);

                    }
                    else if (row[column] is double)
                    {
                        builder.Append(((double)row[column]).ToString(CultureInfo.GetCultureInfo("en-US").NumberFormat));

                    }
                    else if (row[column] is Array && !(row[column] is byte[]))
                    {
                        if (((Array)row[column]).Length == 0)
                        {
                            builder.Append("NULL");
                        }
                        else
                        {
                            Int32 arrayIndex = 1;
                            foreach (var arrayValue in (Array)row[column])
                            {
                                builder.Append(Escape(arrayValue.ToString()));

                                if (arrayIndex < ((Array)row[column]).Length)
                                    builder.Append(",");

                                arrayIndex += 1;
                            }
                        }

                    }
                    else
                    {
                        throw new Exception(string.Format("System type not supported: {0}", row[column].GetType().Name));
                    }

                    builder.Append((char)34);

                    if (column.Ordinal < data.Rows.Columns.Count - 1)
                        builder.Append(delimiter);
                }
                builder.AppendLine();
            }

            return builder.ToString();
        }
    }
}
